#include "CInput.h"


CInput::CInput()
{
	m_pInput			=	NULL;
	m_pKeyboardDevice	=	NULL;
	m_pMouseDevice		=	NULL;

	ZeroMemory( &m_MouseState , sizeof(DIMOUSESTATE) );
}

CInput::~CInput()
{
	Release();
}

//--------------------------------------------------//
// Name : Release                                   //
// Desc : Use to release object , free memory etc.. //
//--------------------------------------------------//
void CInput::Release()
{
	//Release Keyboard
	m_pKeyboardDevice->Unacquire();
	m_pKeyboardDevice->Release();
	m_pKeyboardDevice = NULL;

	//Release Mouse
	m_pMouseDevice->Unacquire();
	m_pMouseDevice->Release();
	m_pMouseDevice = NULL;

	//Release Direct input object
	m_pInput->Release();
	m_pInput = NULL;

	ZeroMemory( &m_MouseState , sizeof(DIMOUSESTATE) );
}


//----------------------------------------------------------------------------//
// Name : CreateInput                                                         //
// Desc : Use to create an Input interface and create Mouse , Keyboard Device //
//----------------------------------------------------------------------------//
bool CInput::CreateInput()
{
	HRESULT hresult;
	hresult=DirectInput8Create(GetModuleHandle(NULL),DIRECTINPUT_VERSION,IID_IDirectInput8,(void**)&m_pInput,NULL);

	if(FAILED(hresult))
	{
		MessageBox(0,"Error on Create input object " ,0,0);
		return false;
	}
	//init keyboard device
	hresult=m_pInput->CreateDevice(GUID_SysKeyboard,&m_pKeyboardDevice,NULL);

	if(FAILED(hresult))
		return false;
	
	//init Mouse device
	hresult=m_pInput->CreateDevice(GUID_SysMouse,&m_pMouseDevice,NULL);

	if(FAILED(hresult))
		return false;
	return true;
}

//---------------------------------------------------------------------------//
// Name : InitKeyboard                                                       //
// Desc : Init data format , set coop level , set property ... for Key board //
//---------------------------------------------------------------------------//
bool CInput::InitKeyboard(HWND hwnd)
{
	HRESULT hresult;

	hresult=m_pKeyboardDevice->SetDataFormat(&c_dfDIKeyboard);

	if(FAILED(hresult))
		return false;

	hresult=m_pKeyboardDevice->SetCooperativeLevel(hwnd,DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);

	if(FAILED(hresult))
		return false;

	DIPROPDWORD dipdw;

    dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    dipdw.diph.dwObj        = 0;
    dipdw.diph.dwHow        = DIPH_DEVICE;
    dipdw.dwData            = 256; // Arbitary buffer size


    hresult = m_pKeyboardDevice->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph );
    if (hresult!=DI_OK) return false; 

	hresult=m_pKeyboardDevice->Acquire();

	if(FAILED(hresult))
		return false;

	return true;
}

//----------------------------------------------------------//
// Name : InitMouse                                         //
// Desc : Init data format , set coop  level ,... for mouse //
//----------------------------------------------------------//
bool CInput::InitMouse(HWND hwnd)
{
	HRESULT hResult;

	hResult=m_pMouseDevice->SetDataFormat(&c_dfDIMouse2);
	if(hResult!=DI_OK)
		return false;

	hResult=m_pMouseDevice->SetCooperativeLevel(hwnd,DISCL_NONEXCLUSIVE|DISCL_FOREGROUND);
	if(hResult!=DI_OK)
	{
		MessageBox(0,0,0,0);
		return false;
	}

	hResult = m_pMouseDevice->Acquire();

	if(FAILED(hResult))
		return false;
	
	return true;
}

//-------------------------------------------//
// Name : ProcessKey                         //
// Desc : Getting the key board device state //
//-------------------------------------------//
void CInput::ProcessKey(HWND hwnd)
{
	HRESULT hr = m_pKeyboardDevice->GetDeviceState( sizeof(keys), (LPVOID)&keys);
	if(FAILED(hr))
	{
		hr = m_pKeyboardDevice->Acquire();
		/*while ( hr == DIERR_INPUTLOST || hr == DIERR_OTHERAPPHASPRIO )
			hr = m_pKeyboardDevice->Acquire();*/
	}
	if (IsKeyDown(DIK_ESCAPE)) 
	{
		PostMessage(hwnd,WM_QUIT,0,0);
	}
}

//-----------------------------------------------//
// Name : IsKeyDown                              //
// Desc : Query if the keycode is pressed or not //
//-----------------------------------------------//
int CInput::IsKeyDown(int keycode)
{
	return (keys[keycode] & 0x80) > 0;
}

//---------------------------------------//
// Name : GetMouse                       //
// Desc : Getting the mouse device state //
//---------------------------------------//
void CInput::GetMouse()
{
	HRESULT hr=	m_pMouseDevice->GetDeviceState(sizeof(DIMOUSESTATE2), (void**)&m_MouseState);
	if(FAILED(hr))
	{
		// Mouse lost, zero out mouse data structure.
		ZeroMemory(&m_MouseState, sizeof(m_MouseState));
		// Try to acquire for next time we poll.
		hr = m_pMouseDevice->Acquire();
		/*while ( hr == DIERR_INPUTLOST || hr == DIERR_OTHERAPPHASPRIO || hr == DIERR_NOTACQUIRED )
			hr = m_pMouseDevice->Acquire();*/
	}
}

//----------------------------------------------------//
// Name : MouseButtonDown                             //
// Desc : Query which the button of mouse is pressing //
//----------------------------------------------------//
bool CInput::mouseButtonDown(int button)
{
	return ((m_MouseState.rgbButtons[button] & 0x80)!=0);
}


float CInput::mouseDX()
{
	return m_MouseState.lX;
}

float CInput::mouseDY()
{
	return m_MouseState.lY;
}

float CInput::mouseDZ()
{
	return m_MouseState.lZ;
}